Размышляя на тему реализации "внутренних" ldir-ов, я подумал: что, собственно, происходит
в разных ситуациях при таких пересылках? Например, ldi из ОЗУ в видеопамять - сначала байт
читается из обычной страницы ОЗУ, потом записывается в перехватываемую страницу - и
одновременно в видеопамять через логическую операцию с регистрами-защелками. И наоборот,
для ldi из видеопамяти в ОЗУ сначала в защелки читаются байты, потом они суммируются
какой-то логической операцией и полученный байт через процессор отправляется в ОЗУ.
А при "внутреннем" ldi (то есть когда обращение к обоим адресам источник/приемник
перехватывается видеокартой) что произойдет? То и другое - читаются байты, суммируются,
полученный байт процессором отправляется в ОЗУ - и одновременно обратно в видеопамять.
То есть во все слои попадают одинаковые байты, что очень плохо. Очевидно, что от проца
требуются только адреса приемника и источника, а данные не нужны - и если байт данных при
записи проигнорировать, то в адрес-приемник в видеопамяти попадет содержимое защелок,
полученное перед эти при чтении, то есть произойдет параллельная пересылка, чего мы и
добивались!
Спрашивается, как понять, когда игнорировать данные при записи, а когда нет? Не делать
же анализатор кода на видеокарте с отловом нужных команд... Можно поступить так:
если сразу после попытки чтения происходит попытка записи (то есть между ними не было
выборки новой команды - сигнал M1 не появлялся), тогда игнорируем. А если после выборки
сразу идет запись, тогда безусловно пишем, что на шине.
Понятно, что такой ldi годится только для параллельного копирования данных в видеопамяти,
то есть прежде всего для "побайтных" прокруток изображения. Вот если бы можно было делать
такие пересылки с учетом логических операций! А для этого нужно просто ввести "второй
комплект" регистров-защелок (то есть теперь имеем отдельные для чтения и для записи) и
распараллелить схему выполнения логических операций. А заодно дать возможность отдельно
выбирать базовые 16K страницы видеопамяти для чтения и записи. То есть запись происходит
так: байт, поступивший от проца, распределяется по Ч-защелкам, одновременно заполняются
данными из видеопамяти З-защелки, выполняются логические операции и результат из З-защелок
записывается обратно в видеопамять. А вот при выполнении "внутреннего" ldi прочитанные из
видеопамяти байты сначала попадут в Ч-защелки, суммируются "на выход" (результат отдается
процу) и остаются в Ч-защелках. Теперь, когда придет запрос на запись, Ч-защелки
байтом, поступившим по шине, не заполняются, а сразу производятся логические
операции с заполненными из адреса записи З-защелками и собственно запись в видеопамять.
Добавить к этому возможность записи "со сдвигом" и "зеркальной" записи, как раньше.