Алгоритм простейший. Но, требует много ресурсов и больших изменений в коде.
Эмуляцию делаем не на основе инструкций, а на основе тактов. Каждая команда Z80 разбивается на циклы и такты. На каждом такте делаем проверку. Если в этом такте читаем или пишем ОЗУ (только ОЗУ), то в этом такте ничего больше не делаем. Иначе вычисляем какой должен быть адрес пикселей или атрибутов на текущем такте кадра. В зависимости от флип-флоп флага считываем из памяти байт пикселей или атрибутов. Сохраняем этот байт в буфере экрана на своем месте. Перекидываем флип-флоп флаг. По достижению конца кадра по информации в буфере строим изображение экрана. Вот и все.