На самом деле между PC XT и 48-ю (!) светодиодами притаился "рояль в кустах":

Эта плата была спонтанно приобретена на ebay. Ясных планов её использования у меня не было, просто захотелось, да и сейчас не такой большой выбор старого ISA-железа, в особенности 8-битного.
На этой плате установлены сразу 2 чипа 8255 и одна микросхема 8253. 8253 мы в этой публикации использовать не будем. Сверху видны 2 40-пиновых гребёнки для подключения шлейфов. Слева - 16 светодиодов, о них чуть позже.
В двух словах о 8255. Она предоставляет доступ к 24 линиям ввода/вывода - к трём 8-битным портам Port A, Port B и Port C. Микросхема может работать в нескольких режимах, мы же будем использовать самый элементарный - просто будем класть байт в порт.
Светодиоды слева на карте подключены к Port A каждой из двух 8255. Уж не знаю, зачем это было реализовано, возможно, просто для демонстрации работоспособности. Но именно наблюдение за чарующим перемигиванием светодиодов и подвело меня к замыслу "вытащить" все 48 линий наружу и сделать, таким образом, светодиодную матрицу.
Плата приехала вместе с подробнейшей книжицей, в которой была принципиальная схема, описание режимов работы 8255 и 8253 и распиновка верхних гребёнок.

Делаем печатные платы
Сначала упомяну комп, к которому всё это будет подключаться - публикация на хабре.
Решил разделить собственно светодиодную матрицу от всей прочей нехитрой логики, поэтому плат было две:
Основная плата:

Сверху вниз:
гнездо подключения светодиодной матрицы (аноды), находится с обратной стороны
6 330-омных резисторных сборок
1-й разъем к плате c 8255-ми
4 логических инвертора 74HC04N
гнездо подключения светодиодной матрицы (катоды), находится с обратной стороны
ещё 4 логических инвертора 74HC04N
2-й разъем к плате c 8255-ми
Аноды светодиодов подключены через резисторные сборки к +5В, катоды подключены к выходам инверторов. Входы инверторов подключены к портам 8255-х.
Светодиодная матрица

Сверху, соответственно, выведены аноды, снизу - катоды. Светодиоды на этом виде на обратной стороне платы. Если же смотреть со стороны светодиодов, то вертикальные ряды идут слева направо в порядке: Port A, Port B, Port C первой 8255, Port A, Port B, Port C второй 8255.
Для разработки плат использовал онлайн редактор easyeda.com. Особых проблем при проектировании не возникло, но было много мороки правильно соотнести 6 портов и 48 светодиодов. Разводка платы прошла автоматическая.
Готовые платы
Платы заказывались на jlcpcb.com.
Платы из посылки

Платы с установленными деталями:
вид спереди:

На дворе дефицит чипов, поэтому копеечные инверторы бережно установлены в панельки!
вид сзади:

Готовый "бутерброд"

Подключённый и закреплённый на раме:

Программируем всё вот это вот, наконец...
Даёшь ретро-железу винтажную IDE!

Да, пришлось активировать нейронные связи, когда-то давно отвечавшие за навыки работы в Turbo Pascal. А также мышечную память, ответственную за Ctrl-K B, Ctrl-K K, Ctrl-K C, Ctrl-Y и так далее.
Немного подробностей
Первоначальная инициализация: готовим рандомайзер, переключаем 8255-е в режим простого чтения/записи в порт, гасим все светодиоды.
Код:
Procedure AllOff; Forward;
Procedure Init;
Const PORT1_CONTROL_REGISTER = $01B3;
PORT2_CONTROL_REGISTER = $01B7;
Begin
Randomize;
Port[PORT1_CONTROL_REGISTER]:=$80;
Port[PORT2_CONTROL_REGISTER]:=$80;
AllOff;
End;
Procedure AllOff;
Begin
MATRIX[0]:=0;
MATRIX[1]:=0;
MATRIX[2]:=0;
MATRIX[3]:=0;
MATRIX[4]:=0;
MATRIX[5]:=0;
Update;
End;
Передаём сформированный массив в порты. Тут я решил заменить унылые Port[xxxx]:=yyyy на ассемблерную вставку.
Код:
Var MATRIX : Array [0..5] of Byte;
Procedure Update;
Const PORT_1A = $01B0;
PORT_1B = $01B1;
PORT_1C = $01B2;
PORT_2A = $01B4;
PORT_2B = $01B5;
PORT_2C = $01B6;
Begin
asm
LEA DI, MATRIX
XOR BX, BX
MOV DX, PORT_1A
MOV AL, [DI+BX]
OUT DX, AL
INC BX
MOV DX, PORT_1B
MOV AL, [DI+BX]
OUT DX, AL
INC BX
MOV DX, PORT_1C
MOV AL, [DI+BX]
OUT DX, AL
INC BX
MOV DX, PORT_2A
MOV AL, [DI+BX]
OUT DX, AL
INC BX
MOV DX, PORT_2B
MOV AL, [DI+BX]
OUT DX, AL
INC BX
MOV DX, PORT_2C
MOV AL, [DI+BX]
OUT DX, AL
end;
End;
Здесь находится репозиторий с исходным кодом.
Заключение
Здесь можно увидеть демонстрацию работы. Качество видео получилось так себе, в реальности все гораздо лучше.
Что дальше? Я первоначально хотел насверлить в непрозрачном оргстекле толщиной 3 мм 48 отверстий и "надеть" на светодиоды, чтобы отделить их друг от друга, а сверху - уже прозрачное красное оргстекло. Специально для этого подбирал цилиндрические светодиоды с плоской шляпкой. Сейчас уже не уверен, хватит ли у меня запала.
Что более вероятно, так это то, что я займусь вторым чипом на плате - 8253. Там 3 независимых счетчика, возможно, я после визуальных эффектов перейду к аудио. Ясно, что это будет весьма и весьма примитивная "музычка". Посмотрим!
Комментарии (14)
tronix286
10.01.2022 09:31+8Да, таймер ВИ53 в принципе неплохо может в музыку, ПК Вектор-06Ц тому подтверждение: https://www.youtube.com/watch?v=9Lxo2NIVpiQ
По поводу кода:
1) не обязательно использовать индексную адресацию с базой (или как там она, которая DI+BX). Достаточно только индексной, то есть lea di,MATRIX; mov al,[di], inc di, mov al,[di] ; inc di; mov al,[di] и тд. То есть увеличиваем только DI. Я точно не помню, но вроде оно по размеру кода меньше получится, а значит и быстрее.
2) можно загрузить смещение в SI, DS у нас и так настроен в пасцале на Data segment и юзать вообще lodsb, типа lea si,MATRIX; lodsb; out dx,al; lodsb; out dx,al и тд.
3) Ну и раз адреса портов идут почти подряд, не обязательно каждый раз перезагружать DX новым значением. Достаточно установить mov dx, PORT_1A, а в следующий раз просто увеличивать DX (inc dx). Inc dx будет быстрее, чем перезагрузка dx из памяти.
Всё это актуально для XT-системы, где в принципе, важен каждый такт. Поэтому вроде мелочи (особенно для какого-нибудь iP166 MMX), а на общем быстродействии сказывается.
tnt23
10.01.2022 11:58+2И не только в музыку. Раз уж тут мигают светодиодами, то режим ШИМ у 8253 тоже можно было бы задействовать.
smart_pic
10.01.2022 09:54Чип 8255 , в нашей стране больше известный как К580ВВ55 - достаточно распространеный чип для ввода вывода. Практически на всех восьмибитных компютерах(и не только) стоял такой чип. Очень удобно на одном таком чипе организовать чтение клавиатуры на 64 и более клавиш , сделать светодиодную индикацию режимов работы клавиатуры.
В Радио86РК , как и на этой плате, стояли два чипа К580ВВ55 и один К580ВИ53. Один К580ВВ55 работал с клавиатурой, а второй был отдан на нужды пользователя.
tnt23
10.01.2022 12:01+5(зануда ON)
Штатно ВИ53 в "Радио-86РК" не было. Его подключали кто во что горазд - радиолюбители как положено, с использованием всех 3 каналов для звука, а редакция журнала "Радио" странным образом, с одним каналом на звук и другим - для управления длительностью звука.
Ну а штатно ВИ53 стоял в "Микроше".
(зануда OFF)
Caraul
10.01.2022 15:16+2мышечную память, ответственную за Ctrl-K B, Ctrl-K K
Еще можно мнемонически - Ctrl-K B - Begin, Ctrl-K K - Конец.
dlinyj
10.01.2022 15:55Потрясающая статья. Спасибо за неё.
Единственная просьба на будущее картинки не класть под спойлеры.
drauger
10.01.2022 16:19Когда я слышу «светодиодная матрица» и «48 линий», я думаю о матрице 24 х 24. Почему всего 6 х 8?
infund Автор
10.01.2022 21:31+1Почему всего 6 х 8?
Потому что с матрицей 24х24 я бы разорился на светодиодах!
Это шутка, конечно. Мысль интересная, но на первый взгляд кажется, что это потребует совершенно других трудозатрат при написании софта.
VolodjaT
10.01.2022 16:48+1На дворе дефицит чипов, поэтому копеечные инверторы бережно установлены в панельки!
После покупки электрического оловоотсоса полностю перестал бояться выпаивания выводных компонентов
https://www.aliexpress.com/item/4001026864070.html
я был в восторге - наверное полчаса выпаивал разные датали с мусорных плат
секунда - две на вывод и микросхема просто выпадает с платы
обзор на eevblog
https://www.youtube.com/watch?v=Ft50m8UU5WQ
commanderxo
11.01.2022 00:16Интересная ISA-карточка, а как она называлась, для чего первоначально предназначалась?
infund Автор
11.01.2022 00:30+3Да в принципе она небрендовая какая-то. Если загуглить "isa 8255 8253", то в разделе Images можно увидеть похожие, обозначенные как "8255 i/o card"
Например, вот такую монструозину (восемь 8255-х и две 8254-х):
echo10
поправьте меня, если ошибаюсь.
В ассемблерной вставке у вас смещение в регистре BX увеличивается на 1, а элементы массива могут быть выравнены в памяти.
Предлагаю писать:
Var MATRIX : PACKED Array [0..5] of Byte;
Это более универсальный вариант для low-level разработки, когда нужен доступ к последовательным участкам памяти (например, при работе с видеобуффером, областями BIOS или с DMA) исключающий зависимость от настроек этого самого алигна в проекте или при явном задании выравнивания директивой {$A}, что тоже может быть полезно для увеличения производительности всей программы.
vicsoftware
В Turbo Pascal не используются разряженные массивы. По сути - они всегда packed.