Вейтовые порты - это эмуляция внешних устройств через бортовой МК (атмега).
К вейтовым портам относятся следующие устройства:
- COM-port (RS-232), сюда же входит и ZiFi,
- Глючасы и CMOS-память в них.
Поскольку атмеге требуется время на обработку запроса, з80 при обращении к вейт портам аппаратно вешается сигналом ~WAIT (отсюда название), пока требуемые данные не будут приняты/отправлены атмегой. В момент активации вейта на атмегу идет сигнал прерывания. Атмега вылетает на ISR, где устанавливается флаг "было прерывание от вейтовых портов". Ничего более не происходит, и обработка вейтового события произойдет в порядке очереди тасок.
Вопрос: почему нельзя обрабатывать вейтовые запросы сразу на ISR?
Ответ: потому что сами процедуры эмуляции этих устройств весьма объемны, поэтому иср обвешивается тонной push/pop и все становится очень плохо. К тому же, пришлось бы обеспечивать межтредовую коммуникацию между иср и основным циклом (хотя бы то же фифо пс/2).
Когда наконец доходит до обработки, атмега обменивается с фпга данными по SPI интерфейсу, в котором атмега выступает мастером, а фпга - слейвом. Стандартный протокол выглядел следующим образом:
- атмега принимает байт статуса, в котором указан тип устройства (ком/часы) и режим доступа (чтение/запись),
- посылает выбор регистра адреса (каждое устройство имеет внутри себя пул регистров),
- принимает адрес,
- посылает выбор регистра данных,
- посылает/принимает байт данных.
После этого вейт с з80 снимается и он продолжает работу.
Я оптимизировал протокол, добавив в байт статуса 5-битный адрес в упакованном формате. Теперь сокращенный протокол выглядит так:
- атмега принимает байт статуса с типом устройства, режимом доступа и упакованным адресом,
- посылает/принимает данные.
Не все адреса можно упаковать в 5 бит, но можно те, к которым требуется максимальная скорость доступа. В данный момент так:
- COM/ZiFi - полностью попадает в 5-битный адрес,
- GluClock, диапазон #F0..#FF - попадает в 5 бит, здесь живут фифо PS/2 клавиатуры и SPI Flash,
- GluClock, диапазон #00..#EF - работает по старому протоколу, тут скорость не критична.
Вторая и более важная новость - фикс генерации вейта/прерывания в фпга.
Оригинальный говнокод содержал трэшовый адъ баг, который приводил к нестабильной генерации сигнала вейта/прерывания, и самое плохое, что в силу своей специфики проявлялся в зависимости от сборки квартусом. При самом неудачном стечении обстоятельств, некоторые обращения к вейтовым портам не доходили до атмеги и нормальная работа с компортом и цмосом была невозможна.