ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Суббота
20 июля
1435185 Топик полностью
RxTx (17.05.2024 18:33, просмотров: 39) ответил Adept на но у LDIR автоинкремент и не надо тратить такты на коррекцию индексных регистров и контроль окончания цикла копирования и побайтово получается сильно быстрее (если конечно тупо не забивать память командами явного копирования байта по адресам (новым в каждой команде). По привязкам к прерыванию 50Гц понятно. (это даёт выравнивание интервалов работы с экранным ОЗУ по кадрам)
Вот это "выравнивание интервалов работы с экранным ОЗУ по кадрам", и дает полнейшую плавность графики. В некоторых ЖК/OLED микро-дисплейчиках есть регистр либо номера строки, либо начала скана кадра. Его всегда надо считывать и таким образом синхронизировать обновление экранного ОЗУ. 

У LDI тоже есть инкремент регистровых пар HL, DE и декремент BC, установка флага в регистре флагов BC == 0 ?) но она в отличие от LDIR не "зацикливается", в этом и всё отличие.

Кстати, если кто не знает как в Z80 сделаны повторяющиеся/цепочечные команды - он каждый раз декрементирует счетчик команд на 2 и с каждой итерацией выполняет команду LDIR снова и снова.

Код команды LDIR в ОЗУ можно стереть/исказить откуда-нибудь из прерывания и её выполнение таким образом прервется на середине.

LDIR выполняется сам, пока счетчик BC не достигнет нуля. Но микроархитектура Z80 увы, такова, что каждый шаг LDIR по копированию байтов из (HL) в (DE) занимает 21 такт. А LDI делая то же самое, но незацикленно делает это всего за 16 тактов (столько же, как и LDIR на последнем шаге, когда он заканчивает копировать). Это почти всегда играет роль потому что процессор относительно слаб и если строить видео-игровой кадр, у тебя уже не секунда и не 3,5 миллиона тактов, а при кадровой частоте 50Hz это 20мсек и всего лишь 70 000 тактов. Так что приходится выжимать каждый такт и это прям реально, не красивое словцо.


Отсюда идея: если записать в память кучу LDI друг за другом можно получить аналог LDIR копирующий каждый байт не за 21 такт, а за 16 тактов ценой некоторого расхода памяти (обычно в играх надо бывало все-таки экономить память и более 16-32 двухбайтных команд LDI друг за другом редко кто ставил. Группа LDI сама по себе без доп.команд полностью LDIR не заменит, потому что тогда копирование происходит с "гранулярностью" или "дискретностью" в N команд LDI. Но если устроить самомодифицирующийся код (патчить блок LDI) или делать программный JP в цепочку LDI:LDI:LDI ... со смещением, то это будет аналог LIDR но более быстрый.


Были и еще более исхищренные способы копировать с использованием стека: с набором всех регистров, перестановкой стека и сохранением регистров.


Но это примитивная "база".

В реальности для работы с графикой требовалось не просто копирование, а выполнение на лету операций (Dst) = (Dst) XOR (Src) или OR или AND с инкрементами Dst, Src.

Или даже часто более сложный вывод графики с "маской": Dst = Dst AND SrcMask OR SrcSprite: INC Dst; INC Src. И т.д. Для Z80 существовало несколько десятков различных трюков по ускорению кода.


И совершенно уникальна история с "недокументированными инструкциями" Z80,

которые в отличие от каких-то сомнительных, сбойных или хакерских способов на других платформах и процессорах

самые настоящие команды, устойчивые, предсказуемые и стабильно работающие всегда, но из-за спешки не внесенные в документацию.

Спасибо, князь. Вы настоящий дворянин. И программист.