Конфликты на шине и адресное пространство
В компьютере все устройства (ОЗУ, геймпад, экран) обычно сидят на одной общей информационной магистрали — системной шине данных. Представь, что будет, если два человека попытаются одновременно говорить в один микрофон: получится неразборчивый шум. В электронике это называется конфликтом на шине (bus collision): если два устройства одновременно выдадут на шину 1 и 0, произойдёт короткое замыкание или данные превратятся в мусор.
Чтобы этого избежать, процессору нужен строгий регулировщик — Адресный дешифратор (AddrDecoder). Он смотрит, к какому адресу сейчас обращается процессор, и разрешает говорить только одному устройству: RAM — если адрес её, геймпаду — если адрес порта. Все остальные получают приказ «молчать».
На уровне 2.22 ты столкнёшься с этой проблемой вживую: шину данных делят RAM и геймпад, и без дешифратора они будут толкаться одновременно.
Что такое адресное пространство
Каждое устройство, подключённое к процессору, получает свой диапазон адресов — это называется адресным пространством. В статье о дешифраторе команд мы разбирали, как процессор понимает opcode. Теперь на очереди другой дешифратор — адресный: он отвечает не на вопрос «что делать», а на вопрос «кто будет говорить».
В компьютере Ершова адресное пространство делится так:
| Диапазон адресов | Устройство | Сигнал выбора |
|---|---|---|
| 0–223 (0x00–0xDF) | RAM — оперативная память | RAM_SEL = 1 |
| 224–255 (0xE0–0xFF) | Устройства ввода-вывода | IO_SEL = 1 |
Диапазон ввода-вывода дальше делится между устройствами: геймпад, генератор случайных чисел и матричный дисплей получают свои порты — об этом мы подробно поговорим в статье про memory-mapped I/O.
Выходы Адресного дешифратора
AddrDecoder выдаёт два сигнала. RAM_SEL8 — это шинная маска: 0xFF, когда процессор обращается к RAM, и 0x00, когда к устройствам ввода-вывода. IO_SEL — обычный бит, который сообщает, что запрос ушёл в порт ввода-вывода.
Зачем маска, а не просто разрешающий сигнал? Чтобы заставить RAM молчать аппаратно: данные RAM проходят через BusAND с маской RAM_SEL8. Если маска равна 0xFF, данные проходят как есть; если 0x00 — на выходе всегда ноль, и RAM как будто отключена от шины.
Каскад: RAM → BusAND → BusOR
Готовое решение выглядит так: RAM.DataOut → BusAND.A, AddrDecoder.RAM_SEL8 → BusAND.B, выход BusAND → BusOR, а результат BusOR — на шину данных и далее в ALU8.B. Геймпад подключается ко второму входу BusOR.
Когда адрес принадлежит RAM, маска пропускает данные RAM, а геймпад просто не активен. Когда адрес принадлежит устройству ввода-вывода, маска обнуляет данные RAM, и на шине остаётся только геймпад. Конфликт становится физически невозможен.
Два адреса на числах
Разберём два случая. Адрес 200: он лежит в диапазоне 0–223, значит, это RAM. Дешифратор выставляет RAM_SEL8 = 0xFF, данные RAM проходят через BusAND без изменений, геймпад замаскирован. АЛУ видит содержимое ячейки 200.
Теперь адрес 254: он попадает в диапазон 224–255, это порт геймпада. RAM_SEL8 = 0x00 — все биты RAM обнулены, RAM молчит. На шине остаётся только значение кнопок геймпада. Одно устройство, один источник, никакого мусора.
По шагам: 1) ROM отдаёт адрес на вход AddrDecoder.Addr; 2) дешифратор сравнивает его с диапазонами; 3) выставляет RAM_SEL8 и IO_SEL; 4) каскад BusAND/BusOR оставляет на шине ровно одного говорящего.
Частые ошибки
1. Забыть соединить AddrDecoder.Addr с ROM: дешифратор не знает, к какому адресу идёт обращение, и сигналы выбора выдаются неправильно.
2. Подключить RAM напрямую к шине без BusAND: тогда RAM будет выдавать данные даже при обращении к порту ввода-вывода.
3. Считать, что «два источника на шине — это нормально»: это короткое замыкание на уровне логики, а не соревнование, где кто-то победит.
Резюме
1. Шина данных общая, поэтому одновременно на неё может выходить только одно устройство.
2. Адресное пространство: 0–223 — RAM, 224–255 — устройства ввода-вывода.
3. AddrDecoder выдаёт маску RAM_SEL8 (0xFF или 0x00) и бит IO_SEL.
4. Каскад RAM → BusAND (с маской) → BusOR (с геймпадом) аппаратно запрещает конфликт.
5. Адрес 200 читает RAM, адрес 254 читает геймпад — и никогда одновременно.
На уровне 2.22 тебе предстоит подключить Адресный дешифратор и собрать каскад из BusAND и BusOR так, чтобы RAM и геймпад никогда не выходили на шину одновременно. После этого компьютер научится читать кнопки — и мы перейдём к вводу-выводу.