Aline: Синхронизация цветов
Резюме
Традиционные проблемы, связанные с использованием multicolor в программах ZX Spectrum, включают:
Написание точно настроенного кода отображения.
Регулировка таймингов синхронизации вручную для ее выполнения в нужный момент.
Остальная часть вашей программы влияет на общее время.
Алине, техника, представленная в этой статье, направлена на то, чтобы полностью избавиться от проблем 2 и 3.
Объяснение
Aline - это идея синхронизации, которую читают плавающие шины, доведенные до логического завершения. Первоначально чтение из незанятого порта «ULA» использовалось рядом игр ZX Spectrum вместо того, чтобы полагаться на прерывания, главным образом, чтобы увеличить время для рисования в кадре. Однако мы обнаружили, что с помощью этого механизма можно добиться стабильной синхронизации в одном T-состоянии точности.
В этой статье в основном обсуждается синхронизация с верхней частью области экрана, которая обычно используется в большинстве случаев. Другие алгоритмы, которые позволяли бы синхронизировать с произвольной символьной линией, также были бы возможны, но более сложными.
Давайте взглянем на краткое изложение цикла цикла плавающей шины на странице Sinclair FAQ Wiki. Можно видеть, что шаблон не является случайным и существует корреляция между адресами экрана и их содержимым и значениями, возвращаемыми в определенных T-состояниях. Поэтому, если мы заполняем некоторые строки растрового изображения / атрибута уникальными идентификационными кодами маркеров синхронизации, становится возможным однозначно рассказать, где мы находились во время чтения.
Идея aline переинтерпретирует эти коды синхронизации как фактическое дополнительное время задержки состояния T от текущего растрового местоположения до конца строки. Когда один из них считывается обратно, выполнение задерживается для этого множества состояний T, поэтому возобновляется в том же постоянном состоянии T в конце строки.
Чтобы это сделать, нам нужен способ убедиться, что у нас всегда есть хотя бы один битмап / атрибут, считываемый с самой первой строки сканирования экрана. Это может быть достигнуто за счет того, что входной цикл принимает нечетное число состояний T, которое близко к кратным 8, будучи достаточно быстрым. Таким образом, выполнение будет постоянно «дрейфовать» относительно шаблона плавающей шины и, в конечном итоге, достигнет либо растрового изображения, либо области атрибута в шаблоне. Прежде чем это произойдет, значения простоя 255 из граничной или пустой части шаблона, встречающиеся в цикле, просто игнорируются. В течение активной области экрана на линии (128 T состояний) одна итерация цикла из 25 T состояний (8 * 3 + 1) может повторяться 4-5 раз, что достаточно для этой цели.
Код:
ld e,2
call .sync
...
.sync
ld hl,.sync_lp
ld bc,#FFFF
.sync_lp
in a,(c)
cp e
ret p
jp (hl)
Что касается инициализации верхней строки с помощью значений маркера синхронизации, имейте в виду, что нет необходимости заполнять каждый бит атрибута и битмапа. Единственное требование здесь - убедиться, что «расстояние между образцами» между двумя значениями маркера не превышает 4. Остальные байты должны быть установлены равными нулю или любым другим значением, которое будет игнорироваться циклом.
Обратите внимание, что в рамках этой схемы ожидается, что алгоритм aline будет работать исключительно во время нижней / верхней границы, что может быть не всегда так. Поэтому его нужно будет дополнить еще одним фрагментом кода, который задерживает выполнение до тех пор, пока растр не окажется на нижней / верхней границе. Следующий или аналогичный код включен во все версии aline.
Код:
SyncBorder
ld hl,#4000
ld (hl),#FF ;+2A/+3 обходной путь (см. ниже)
ld d,4 ;D = количество последовательных чтений
ld bc,(Aline.LOC_Port)
.lp1
ld e,d
.lp2
ld a,(hl) ;+2A/+3 обходной путь
in a,(c)
inc a
jr nz,.lp1
dec e
jr nz,.lp2
ret
Наконец, из-за характера этой техники некоторые артефакты атрибутов могут быть оставлены видимыми в верхних строках сканирования. Стандартная реализация aline пытается замаскировать это для первых двух строк сканирования, визуально оставив их черными. Если вызывающая программа сразу начинает заполнять экран полноцветными многоцветными данными, на экране не будет отображаться никаких артефактов. Если ширина многоцветной области меньше этой, может потребоваться дополнительная работа, чтобы установить атрибуты края на ноль. Вариант 4T mod aline, рассмотренный ниже, не пытается полностью маскировать артефакты атрибутов, так как в этом случае атрибуты используются исключительно, с общим 32 кодами синхронизации, что не позволяет обнулить INK или бит PAPER в кодах.
Вариант «Цвет» стандартной реализации aline позволяет изменить цвет области маркера синхронизации. Метод назначения кода маркера синхронизации изменяется таким образом, что результирующие атрибуты атрибутов сохраняются на минимальном уровне, только в зависимости от настройки BRIGHT для каждой другой ячейки атрибута в половине области маркеров синхронизации по горизонтали. Если цвет установлен на черный, артефакты не будут отображаться, как в стандартной версии.
Преимущества:
Многоцветная совместимая синхронизация простым способом, подобным выпуску HALT
Свободное время процессора может быть эффективно использовано, и ограничение на несвязанное по срокам ветвление отменяется
Многоцветная программа может быть написана, как и любая другая, со сравнительно небольшим количеством особых соображений, ожидаемых от таких произведений, вне настройки самой части кода отображения
В результате потенциальная сложность многоцветного программного обеспечения значительно возрастает.
Недостатки:
Требует модели ZX Spectrum, которые реализуют некоторую форму функциональных возможностей плавающей шины
Доступное пространство экрана уменьшается на 3 строки сканирования в зависимости от алгоритма
Таким образом, более сложное соединение с чем-то другим, чем верхняя часть экрана
Артефакты верхней сканирующей линии, которые могут маскироваться или не маскироваться в зависимости от алгоритма.
Совместимость.
*
Модели Sinclair и Amstrad ZX Spectrum
До сих пор подтверждается, что aline работает как ожидается при эмуляции на всех конфигурациях Sinclair ZX Spectrum вплоть до +2 (SpecEmu, Spectaculator, Fuse), а также на конфигурации Amstrad ZX Spectrum +3 (SpecEmu) с некоторыми ограничениями ,
Что касается моделей + 2A / + 3, то недавно было обнаружено, что на них можно получить доступ к функциям плавающей шины. В частности, было обнаружено, что шаблон выборки аналогичен шаблону Sinclair с несколькими заметными отличиями:
Он реагирует на адреса портов с помощью маски 0000XXXXXXXXXX01b в режиме 128K
Значения, возвращаемые с порта плавающей шины, имеют бит 0, установленный
Значение атрибута, предшествующего незанятой части в шаблоне, возвращается вместо 255
Значение бездействия границы изменяется после доступа доступной памяти
Таким образом, одна итерация шаблона выборки + 2A / + 3 над областью PAPER может выглядеть так (Bitmap, Attribute):
B0 A0 B1 A1 A1 A1 A1 A1
Первые две точки, перечисленные выше, учитываются при стандартной реализации aline. Третья точка, с другой стороны, уменьшает полезность четвертых атрибутов в шаблоне выборки, эффективно уменьшая точность синхронизации от 1 до 5 T состояний. Следует, однако, отметить, что эта уменьшенная точность обычно достаточна на практике, учитывая характер применения такого метода и такие факторы, как конкуренция памяти. Кроме того, в какой-то момент, вероятно, появится специальный алгоритм для решения этой проблемы.
Другое значение здесь заключается в том, что не существует значения idle по умолчанию, которое возвращается во время границы на + 2A / + 3. То, что обычно читается в этом случае, - это самые правые атрибуты каждой отдельной строки символов. Однако, если во время пограничного времени доступ к адресу памяти процессора запрашивается ЦП, значение незанятости, возвращаемое из порта FB, устанавливается на содержимое этого адреса. Это новое значение простоя остается в силе до тех пор, пока растр не перейдет через область экрана. Стандартная реализация aline также объясняет это.
Неофициальные мотивы плавающих автобусов «ATTRIBUTE ONLY»
Теоретически модификация алгоритма позволила бы использовать вариант aline для совместимых с Spectrum-совместимых модулей с плавающей шиной с упрощенной функцией, которые возвращают только значения атрибутов для каждого состояния 4 T. Для получения точной синхронизации 1Т требуется 3 чтения. Следует отметить, что эта форма aline не легко взаимозаменяема с алгоритмом для оригинальных машин, поскольку для последнего требуется только одно чтение.
Схема такова. Продолжайте читать плавающий порт шины до тех пор, пока не получится отличное от нуля чтение A. Выполнение задержки для состояний TStatesPerLine + 2 T, по существу перемещая 2 T состояния по отношению к шаблону и сделайте второе считывание порта B. На данный момент существует две ветви в зависимости от того, является ли A = B:
Если A = B, мы в настоящее время находимся в T-состояниях 1 или 2 из 4. Для того чтобы сделать это ясно, третье чтение C должно быть выполнено после состояний TStatesPerLine-3 'T. Если C = A, мы находимся в состоянии T 1/4. Если C ≠ A, мы находимся в состоянии T 2/4.
Если A ≠ B, мы в настоящее время находимся в T-состояниях 3 или 4 из 4. Чтобы сделать это ясно, третье чтение C должно быть сделано после состояния TStatesPerLine-1 'T. Если C = A, мы находимся в состоянии T 3/4. Если C ≠ A, мы находимся в состоянии T 4/4.
Код:
A=(+0)
B=(+2), 'T states per line + 2' later
A=B: case 1: 1/4 or 2/4
---CA-B-----
----CA-B----
000011112222
C=(-1), 'T states per line - 3' later
C=A: 1/4, else 2/4
A≠B: case 2: 3/4 or 4/4
------ACB---
-------ACB--
000011112222
C=(+1), 'T states per line - 1' later
C=A: 3/4, else 4/4
Однако, как указывалось ранее, даже на практике практика снижения точности (4T в данном случае) была бы достаточной, и ее можно было бы достичь с помощью одного считывания точно так же, как в исходном алгоритме. В обоих случаях только атрибуты должны быть настроены как значения маркера синхронизации.
Ожидаемый недостаток обоих вариантов алимента-алина заключается в том, что может быть невозможно маскировать артефакты атрибутов в верхних строках сканирования экрана, поскольку оба метода полностью основаны на атрибутах.
Ресурсы
Исходный код для aline доступен здесь. Включены следующие файлы:
aline.asm: стандартная реализация
aline-color.asm: позволяет изменять цвет области синхронизации
aline-fast.asm: использует развернутый (оптимизированный по скорости) код установки
aline-attronly-4t.asm: неофициальный вариант с атрибутом «только для атрибутов» с плавающей шиной (точность 4T)
test-aline.tap: простой тест для алина с использованием многоцветного режима 8x1
Для примера использования aline доступна демонстрация движка Mint CatS от Intense.
Скачать архив (.TAP)
Смотреть демонстрацию
Special thanks
Chernandezba, Ast A. Moore, Your Spec-chum, Woody, Weiv and everyone else of the +2A/+3 floating bus testing effort over at the World of Spectrum forums.
[свернуть]