THE COMPLETE AMIGA HARDWARE
REFERENCE MANUAL

                                  Глава 2

                                  КОППЕР

КОППЕР

Коппер   -  сопроцессор  общего назначения, располагающийся в одном из
заказных  чипов  Амиги.  Он  исполняет команды, передаваемые с помощью
DMA.   Коппер   может   управлять  почти  всей  графической  системой,
освобождая  68000  для  выполнения  логики  программы,  он может также
влиять  на  содержимое  большинства  регистров чипсета. Это прекрасный
инструмент  для  прямого  изменения содержимого экрана и для изменения
содержимого  регистров,  которое должно происходить во время обратного
хода  луча.  Кроме  этого, коппер может обновлять регистры, перемещать
спрайты,  изменять  палитру  экрана, влиять на вывод звука и управлять
блиттером.

Одна  из  особенностей  коппера это его способность ЖДАТЬ определенной
позиции  видео  луча, а затем ПЕРЕМЕЩАТЬ данные в системный регистр. В
период ожидания коппер напрямую проверяет содержимое счетчиков позиции
видео-луча.  Это  позволяет  копперу  не использовать шину, находясь в
режиме  ожидания.  Следовательно, шина освобождается для использования
другими каналами DMA или 68000.

Когда  ожидание  завершается,  коппер  берет  цикл шины у блиттера или
68000 для перемещения данных в заданный регистр.

Коппер  -  двух-цикловый  сопроцессор,  требующий шину только во время
нечетных  циклов  памяти. Это предотвращает столкновения со следующими
каналами DMA: звуковым, диска, экрана и спрайтов. Следовательно коппер
нуждается  в  приоритете  только над блиттером (канал DMA, управляющий
анимацией, заливкой и рисованием линий) и 68000.

Как и все другие каналы DMA, коппер может выбирать свои команды только
из chip памяти.

ОБ ЭТОЙ ГЛАВЕ
В  этой главе вы научитесь использовать коппер для изменения регистров
в  середине  экрана и во время обратного хода луча. Также показано как
объединять команды коппера в копперлист, как использовать копперлист в
режиме  интерлейса,  как  использовать  коппер  совместно с блиттером.
Коппер  обсуждается в общем виде. Главы, посвященные экрану, спрайтам,
звуку и блиттеру содержат специфические примеры использования коппера.

ЧТО ТАКОЕ КОМАНДА КОППЕРА?
Как   сопроцессор,   коппер   добавляет  свои  собственные  команды  к
существующим  у  68000. Коппер имеет только 3 команды, но с ними можно
сделать очень много.

- WAIT (ЖДАТЬ) позиции на экране, определенной координатами x и y.
- MOVE (ПЕРЕМЕЩАТЬ) данные в заданный адрес памяти
- SKIP (ПРОПУСКАТЬ) следующую команду, если луч достиг позиции x,y

Все  команды  коппера состоят из двух 16-ти битных слов, расположенных
последовательно.  Каждая  выборка команды коппером выбирает оба слова.
Команды  MOVE  и  SKIP требуют два цикла памяти для выборки. Поскольку
коппер   использует  только  нечетные  циклы,  требуется  4  цикла  по
времени  выполнения.  Команда  WAIT  требует  3  цикла для выборки и 6
циклов по времени, один цикл требуется для пробуждения.

Хотя коппер может влиять только на регистры чипсета, он может влиять и
на  память  с  помощью  блиттера.  О  том,  как коппер может управлять
блиттером  читайте  разделы  'Регистр управления'  и  'Использование
коппера с блиттером'

Команды  WAIT  и  MOVE  описаны  ниже.  Команда SKIP описана в разделе
'Дополнительные темы'

КОМАНДА MOVE

Команда  MOVE  перемещает данные в память. Данные содержатся во втором
слове  команды,  первое  слово содержит адрес приемника. Эта процедура
показана в деталях в разделе 'Обобщение команд коппера'

            ПЕРВОЕ СЛОВО КОМАНДЫ (IR1)

    бит   0   Всегда  0.
    биты  8 - 1 Адрес регистра-приемника (DA8-1).
    биты 15 - 9 Не используются, но должны быть 0.

            ВТОРОЕ СЛОВО КОМАНДЫ (IR2)
    биты  15  -  0  16  бит данных для перемещения в регистр-приемник.

Коппер может записывать данные в следующие регистры:
- Любой регистр с адресом $20 и выше
-  Любой  регистр  с  адресом в интервале $10 - $20 если бит опасности
коппера  =1. Этот бит находится в регистре управления коппером COPCON,
который описывается в разделе 'Регистр управления'
- Коппер не может записывать в регистры с адресами меньше, чем $10.

Приложение B содержит адреса всех регистров.

Следующий  пример устанавливает указатель первого битплана на $21000 и
указатель второго битплана на $25000
     DC.W    $00E0,$0002     ;$0002 в регистр $0E0 (BPL1PTH)
     DC.W    $00E2,$1000     ;$1000 в регистр $0E2 (BPL1PTL)
     DC.W    $00E4,$0002     ;$0002 в регистр $0E4 (BPL2PTH)
     DC.W    $00E6,$5000     ;$5000 в регистр $0E6 (BPL2PTL)

Существуют  файлы,  содержащие  определения всех регистров и их адреса
для   использования  в  качестве  файлов  поддержки.  Это  значительно
улучшает  читабельность программы и позволяет более легко адаптировать
вашу программу к другим разновидностям чипсета. Например:

         INCLUDE "hardware/custom.i"

     DC.W    bplpt+$00,$0002 ;$0002 в регистр $0E0 (BPLlPTH)
     DC.W    bplpt+$02,$1000 ;$1000 в регистр $0E2 (BPLlPTL)
     DC.W    bplpt+$04,$0002 ;$0002 в регистр $0E4 (PL2PTH)
     DC.W    bplpt+$06,$5000 ;$5000 в регистр $0E6 (BPL2PTL)

Приложение   J   содержит  расширение  файла  "hardware/custom.i"  для
некоторых  регистров  и для записи имен как большими, так и маленькими
буквами, поскольку многие ассемблеры критичны к регистру символов.

КОМАНДА WAIT
Команда  WAIT  заставляет  коппер  ждать,  пока видео луч не достигнет
(или  не  станет  больше)  позиции, определенной в команде. Находясь в
состоянии ожидания коппер отключен от шины и не использует ее циклы.

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

                         ПЕРВОЕ СЛОВО КОМАНДЫ (IR1)

         бит  0      Всегда 1.
         биты 15 - 8 Вертикальная позиция луча (называемая VP).
         биты  7 - 1 Горизонтальная позиция луча (называемая HP).

                        ВТОРОЕ СЛОВО КОМАНДЫ (IR2)

         бит  0      Всегда 0.
         бит 15      Бит окончание работы блиттера.
                     Обычно этот бит 1.
                     (См. раздел "Дополнительные темы")

         биты  14  -  8  Биты  разрешения  сравнения  для вертикальной
позиции (называемые VE).
         биты  7  -  1   Биты  разрешения сравнения для горизонтальной
позиции (называемые HE).

Следующий  пример  команды  WAIT  ждет 150-й линии ($96) с выключенной
маской горизонтальной позиции.

        DC.W    $9601,$FF00     ; Ждем линию 150,
                                ; Игнорируем горизонтальные счетчики.

Следующий    пример    команды    WAIT    ждет  255-й  линии  ($FF)  и
горизонтальную  позицию  254. Это событие никогда не наступит, поэтому
коппер останавливается до начала следующего обратного хода луча.

        DC.W    $FFFF,$FFFE     ; Ждем линию 255,
                                ; HP = 254 (Конец копперлиста).

Для  понимания  почему позиция VP=$FF HP=$FE никогда не наступит, надо
рассмотреть   операцию   сравнения  коппера  и  ограничения  счетчиков
координат.  255-й  линии  дождаться  можно,  это максимальное значение
вертикального  счетчика. Следующая линия будет появляться на счетчиках
как  нулевая  (линия  256  для коппера нулевая) Горизонтальная позиция
имеет  максимальное  значение $E2. Это значит, что максимальное число,
которое  будет  участвовать  в  сравнении - $FFE2. Когда мы ждем $FFFE
линия  $FF  достигается,  а  горизонтальная  позиция  $FE  никогда  не
наступает. Таким образом позиция $FFFE никогда не наступает.

Вы можете подумать, что можно просто ждать горизонтальной позиции $FE,
(раз  она  никогда  не  наступит) и установить меньшее значения в поле
вертикальной  позиции.  Этим  вы  не  достигнете желаемого результата.
Операция  сравнения  ждет  позиции  большей  или равной заданной. Если
вертикальная  позиция  не  $FF,  то  как  только  номер линии превысит
заданный, так операция ожидания успешно завершится.

Следующие   замечания   по   горизонтальной  и  вертикальной  позициям
относятся  как  к  команде  WAIT,  так  и  к команде SKIP, описанной в
разделе 'Дополнительные темы'

ГОРИЗОНТАЛЬНАЯ ПОЗИЦИЯ ЛУЧА

Горизонтальная позиция луча имеет значение $0 - $E2. Поскольку младший
бит  не  участвует  в сравнении, для коппера доступно 113 позиций. Это
соответствует  шагу  в  4  пиксела  в  низком  и  8 пикселов в высоком
разрешении.  Горизонтальный  обратный ход происходит в интервале $0F -
$35.  Стандартный  экран  (шириной  320 пикселей) имеет неиспользуемую
горизонтальную  область  $04  - $47 во время которой изображается цвет
фона.
В  NTSC  строки  не  одинаковой  длины,  они  бывают  длиной 227 и 228
(0-$E3).  В PAL все строки длиной 227. Контроллер экрана видит все эти
строки  длиной  227  1/2, а коппер может распознать длинные и короткие
строки.

ВЕРТИКАЛЬНАЯ ПОЗИЦИЯ ЛУЧА
Вертикальная  позиция  луча  определяется с разрешением в одну линию с
максимумом  255.  Всего  возможно  262 линии на NTSC (312 на PAL). Для
того,  чтобы  можно  было использовать все возможные линии применяется
следующий метод:

    ЖДЕМ позицию (0,255)  -  В  этой  точке  вертикальный  счетчик
переходит в ноль.
    ЖДЕМ   позицию   256-'требуемая   позиция'   -  поскольку  счетчик
вертикальных  линий  начал отсчет сначала, наша искомая позиция теперь
имеет номер 256-N, которого и дожидается вторая команда WAIT


ПРИМЕЧАНИЕ
Как  по  горизонтали  существуют  длинные  и  короткие линии, так и по
вертикали  существуют  длинные  и  короткие  кадры  (только  в  режиме
интерлейса). В NTSC кадры по 262 и 263 линии,  в PAL 312 и 313 линий.

В интерлейсном NTSC режиме все время повторяется следующий образец:

     короткий кадр заканчивается на короткую линию
     длинный кадр заканчивается на длинную линию
     короткий кадр заканчивается на длинную линию
     длинный кадр заканчивается на короткую линию
     и сначала...

1  горизонтальный  счетчик  берет  1 цикл системных часов (процессор в
два раза быстрее)

     NTSC- 3,579,545 Hz
     PAL- 3,546,895 Hz
     режим генлока- базовая частота плюс-минус 2%.

БИТЫ РАЗРЕШЕНИЯ СРАВНЕНИЯ
Биты  1-14  обычно  включены.  Использование  этих бит описано позже в
разделе 'Дополнительные темы'

ИСПОЛЬЗОВАНИЕ РЕГИСТРОВ КОППЕРА

К копперу относятся несколько регистров чипсета и стробовых регистров

- Регистры размещения
- Стробовые регистры
- Управляющие регистры

РЕГИСТРЫ РАЗМЕЩЕНИЯ

Коппер имеет два регистра размещения:

            COP1LCH старшие 3 бита адреса первого копперлиста.
            COP1LCL младшие 16 бит адреса первого копперлиста.
            COP2LCH старшие 3 бита адреса второго копперлиста.
            COP2LCL младшие 16 бит адреса второго копперлиста.

При   прямом   доступе  к  железу  часто  приходится  записывать  пару
регистров,  содержащих  адрес  некоторых  данных.  Регистр  с  меньшим
адресом  всегда  имеет имя, оканчивающееся на 'H' и содержит 3 старших
бита   адреса.   Регистр   с   большим  адресом   всегда   имеет  имя,
оканчивающееся  на 'L' и содержит 16 младших бит адреса. Следовательно
можно  записать  весь  19-ти битный адрес записав одно длинное слово в
регистр, чье имя оканчивается на 'H'.

В  случае  регистров  размещения коппера данные записываются в регистр
COP1LCH.

Регистры   размещения   коппера   содержат   два   адреса   переходов,
используемых  коппером.  Коппер  производит  выборку команд, используя
программный  счетчик  и  увеличивает  его  после каждой выборки. Когда
происходит   запись   в  стробовый  регистр,  соответствующий  регистр
размещения  загружается  в  программный  счетчик. Это вызывает переход
коппера  в  новое  место  из  которого  и  будут  выбираться следующие
команды.  Команды  выбираются последовательно, до тех пор, пока коппер
не прервется следующей записью в стробовый регистр.

ПРИМЕЧАНИЕ
В   начале   каждого  обратного  хода  луча  копперлист  автоматически
начинает  исполняться  с  адреса  COP1LC  независимо  от  того, где он
находился во время предыдущего кадра.

СТРОБОВЫЕ РЕГИСТРЫ

Когда  происходит    запись    в  стробовый  регистр,  соответствующий
регистр размещения  загружается  в  программный  счетчик. Коппер может
записывать   свои   собственные  регистры  размещения   и  стробы  для
осуществления  переходов.  Например,  можно  записать  адрес в регистр
COP2LC, а затем записать любое значение в COPJMP2, что запустит коппер
с этого адреса.
Существуют два стробовых регистра:

     COPJMP1 перезапускает коппер с адреса, содержащегося в COP1LC.
     COPJMP2 перезапускает коппер с адреса, содержащегося в COP2LC.

УПРАВЛЯЮЩИЙ РЕГИСТР

Коппер   может   иметь   доступ  к  одним  регистрам  все время ($20 -
$FF),  к  другим регистрам только, если включен специальный бит ($10 -
$1F),  а  к  третьим никогда($00 - $0F). (См. приложение B для полного
списка регистров) Управляющий регистр коппера находится как раз в этой
группе  ($00-$0F)  Таким  образом только 68000 может позволять копперу
доступ к определенным регистрам.

Управляющий  регистр  коппера,  называемый COPCON содержит только один
бит,  бит  #1. Этот бит, называемый CDANG (Copper Danger bit) защищает
все  регистры  в  интервале  от $10 до $1F включительно. Этот интервал
содержит  управляющие  регистры блиттера. Когда CDANG = 0 эти регистры
не  могут  быть  записаны  с  помощью  коппера,  когда  =1  то  могут.
Запрещение    копперу    изменять    управляющие   регистры   блиттера
предотвращает   случайное   изменение   системной   памяти,  вызванное
неправильным копперлистом.

ПРИМЕЧАНИЕ
Бит CDANG выключается после ресета.


СОЗДАНИЕ КОППЕРЛИСТА

Копперлист  содержит  команды, которые устанавливают регистры во время
обратного  хода луча и команды, изменяющие регистры в середине экрана.
Вы  можете  планировать копперлисты так, как будто эти части, управляющие
различными    подсистемами,   такими,   как   экраны,  спрайты,  звук,
прерывания    и   т.д.   независимы    одна   от  другой.   Затем   вы
можете объединить эти последовательности  в один  простой  копперлист,
использующий  команду WAIT, а можете создать копперлист из переходов с
одной части на другую.

Например,  указатели  битпланов  и спрайтов должны быть установлены во
время обратного хода луча. Это делает следующий набор команд:

     WAIT первую линию экрана
     MOVE устанавливаем указатель первого битплана
     MOVE ------//-----//-------- второго ---//---
     MOVE ------//-----//--------- первого спрайта
     и т.д.

В  другом  примере,  спрайт  может  быть  повторно изображен на том-же
экране  но  с другими цветами, изменив цвета спрайта после прохождения
лучем  последней линии спрайта +1 при первом его использовании и перед
первой линией при втором использовании.

     WAIT первую линию экрана
     MOVE первый_цвет1 в COLOR 17
     MOVE первый_цвет2 в COLOR 18
     MOVE первый_цвет3 в COLOR 19
     WAIT последнюю линию спрайта +1
     MOVE второй_цвет1 в COLOR 17
     MOVE второй_цвет2 в COLOR 18
     MOVE второй_цвет3 в COLOR 19
     и т.д.

Когда  вы создаете копперлист, проследите, чтобы окончательный вариант
выполнялся  в  такой-же  последовательности,  как  изображается  экран
видео-лучем.  Видео  луч  начинает  рисовать  экран  с позиции (0,0) в
верхнем  левом  углу экрана и заканчивает в позиции (226,262) для NTSC
(или  (226,312)  для PAL) в правом нижнем углу. Первая координата - x,
вторая  -  y.  Команда,  ожидающая позицию (0,100) должна стоять после
команды, ожидающей позицию (0,60).

ПРИМЕЧАНИЕ
В   описании   команды   WAIT   говорилось  почему  инструкции  должны
располагаться  строго  в последовательном порядке. Это потому что WAIT
ждет позицию большую или равную заданной.
Например, если вы запишете команды таким образом:

     WAIT позицию (64,64)
     MOVE данные
     WAIT позицию (60,60)
     MOVE данные

то  коппер  выполнит  оба MOVE в позиции (64,64) т.к. второе сравнение
автоматически  будет  успешным,  вычисляясь  по  формуле  'больше  или
равно'.  По этой же причине не имеет смысла два раза ожидать одну и ту
же позицию:

     WAIT позицию (60,60)
     MOVE данные
     WAIT позицию (60,60)
     MOVE данные

Эта последовательность эквивалентна следующей:

     WAIT позицию (60,60)
     MOVE данные
     MOVE данные

ЗАКОНЧЕННЫЙ ПРИМЕР КОППЕРЛИСТА

Этот  пример  показывает  законченный  копперлист для двух битпланов в
адресах  $21000  и $25000. Вверху экрана цветовые регистры загружаются
следующими значениями:

          РЕГИСТР     ЦВЕТ

          COLOR00     белый
          COLOR01     красный
          COLOR02     зеленый
          COLOR03     синий

На строке 150 цветовые регистры перегружаются:

          РЕГИСТР     ЦВЕТ

          COLOR00     черный
          COLOR01     желтый
          COLOR02     голубой
          COLOR03     фиолетовый

;
; Примечания
;       1. Копперлист должен бить в CHIP памяти.
;       2. Адреса битпланов взяты произвольно
;       3. Регистры приемники адресованы по смещению от базового
;          адреса
;       4. Как всегда подразумевается, что задача полностью
;          контролирует железо и не конфликтует с операционной
;          системой, использующей то-же железо.
;       5. Пример просто использует память, но в программе память
;          должна выделяться с помощью AllocMem()
;       6. Это только пример для того, чтобы понять как работает
;          железо
;       7. Для всех примеров в этой главе требуются следующие файлы
;
          INCLUDE "exec/types.i"
          INCLUDE "hardware/custom.i"
          INCLUDE "hardware/dmabits.i"
          INCLUDE "hardware/hw_examples.i"

COPPERLIST:
;
; Установка указателей двух битпланов
;
     DC.W    BPL1PTH,$0002      ;S0002 в регистр $0E0 (BPL1PTH)
     DC.W    BPL1PTL,$1000      ;$1000 в регистр $0E2 (BPL1PTL)
     DC.W    BPL2PTH,$0002      ;$0002 в регистр $0E4 (BPL2PTH)
     DC.W    BPL2PTL,$5000      ;$5000 в регистр $0E6 (BPL2PTL)
;
; Загрузка цветов
;
     DC.W    COLOR00,$0FFF      ;Белый в регистр $180 (COLOR00)
     DC.W    COLOR01,$0F00      ;Красный в регистр $182 (COLOR01)
     DC.W    COLOR02,$00F0      ;Зеленый в регистр $189 (COLOR02)
     DC.W    COLOR03,$000F      ;Синий в регистр $186 (COLOR03)
;
; Определяем два битплана в низком разрешении
;
     DC.W    BPLCON0,$2200      ;2 lores битплана, цветной вывод
;
; Ждем линию 150
;
     DC.W     $9601,$FF00         ;Ждем  линию  150, игнорируем гориз.
;позицию
;
; Изменяем цвета в середине экрана
;
     DC.W    COLOR00,$0000      ;Черный в регистр $0180 (COLOR00)
     DC.W    COLOR01,$0FF0      ;Желтый в регистр $0182 (COLOR01)
     DC.W    COLOR02,$00FF      ;Голубой в регистр $0184 (COLOR02)
     DC.W    COLOR03,$0F0F      :Фиолетовый в регистр $0186 (COLOR03)
;
; Заканчиваем копперлист ожиданием невозможного
;
     DC.W    $FFFF,$FFFE        ;Ждем линию 255, H = 254

Для  получения  большего  количества  информации о регистрах цвета см.
главу 3 'Экраны'

ЦИКЛЫ И ПЕРЕХОДЫ

Циклы и переходы в копперлистах описаны в разделе 'Дополнительные темы'


ВКЛЮЧЕНИЕ И ОСТАНОВКА КОППЕРА

ВКЛЮЧЕНИЕ КОППЕРА

После  включения  компьютера  или после перезагрузки вы должны занести
адрес  копперлиста  в  один  из  регистров размещения и выдать строб в
регистр   строба.  Обычно  используется  регистр  COP1LC  потому что с
его  адреса  автоматически  запускается  копперлист.  Следующий пример
показывает  как  запустить  коппер.  Подразумевается,  что  копперлист
находится по адресу COPPERLIST
;
; Зaпуск копперa
;
        lea     CUSTOM,a5               ;a5= aдрес регистров чипсетa
        move.l  #COPPERLIST,COP1LC(a5)  ;зaносим aдрес копперлиста
        move.w  COP1JMP(a1),d0          ;выдaем строб
;
; После чего включaем рaстровый dma и dma копперa
;
     MOVE.W  #(DMAF SETCLR!DMAF_COPPER!DMAF_RASTER!DMAF_MASTER),DMACON(a1)

Теперь,  если  знaчение  COP1LC  не  изменять,  кaждый  раз  во  время
обрaтного  ходa лучa коппер будет перезaпускaться с aдресa укaзaнного в
COP1LC   и   если   копперлист  был  написан  прaвильно   ,вы  увидите
стaбильное изобрaжение.

ОСТАНОВКА КОППЕРА

Для   коппера  не  существует  специальной  команды  останова,  однако
заставить  его ничего не делать до конца текущего кадра можно командой
WAIT  с  параметрами VP=255 и HP=254 (эта команда завершает выполнение
копперлиста).
Для  остановки  можно  также  выключить DMA коппера с помощью регистра
DMACON,   который  управляет  всеми  каналами  DMA.  Бит,  управляющий
коппером называется COPEN (бит 7) установка которого включает коппер.
  Для   более   подробного   объяснения  установки  DMA  см.  главу  7
'Управление  чипсетом'

ДОПОЛНИТЕЛЬНЫЕ ТЕМЫ

КОМАНДА SKIP

Команда  SKIP  позволяет  копперу  пропускать  следующую  комaнду если
позиция видеолуча больше или равна позиции, укaзaнной в комaнде.
Ниже  указано  содержание  слов команды SKIP Оно почти такое-же, как у
команды  WAIT  зa  исключением  битa  0  во  втором слове команды - он
включен.

                         ПЕРВОЕ СЛОВО КОМАНДЫ (IR1)

         бит  0      Всегда 1.
         биты 15 - 8 Вертикальная позиция луча (называемая VP).
         биты  7 - 1 Горизонтальная позиция луча (называемая HP).

                        ВТОРОЕ СЛОВО КОМАНДЫ (IR2)

         бит  0      Всегда 1.
         бит 15      Бит окончание работы блиттера.
                     Обычно этот бит 1.
         биты  14  -  8  Биты  разрешения  сравнения  для вертикальной
позиции (называемые VE).
         биты  7  -  1   Биты  разрешения сравнения для горизонтальной
позиции (называемые HE).

Примечaния     относительно    вертикaльной   и горизонтaльной позиции
описaны в рaзделе команды WAIT и точно такие-же, как и у команды SKIP

Следующий   пример команды  SKIP пропускaет  следующую  зa  комaндой
инструкцию если вертикальная позиция луча больше или рaвна 100 ($64).

      DC.W   $6401,$FF01    ; Если VP >= 100,
                            ; пропустить следующую команду (игнорируя HP)

ЦИКЛЫ, ПЕРЕХОДЫ И МАСКИ СРАВНЕНИЯ

Вы  можете  менять  значение  регистров  размещения  в  любое  время и
использовать  это  для  создания циклов в копперлисте. Перед очередным
периодом обратного хода луча значение COP1LC должно быть восстановлено
для указания на начало копперлиста.

Биты  1-14  (маска)  во  втором  слове  команд WAIT и SKIP определяют,
какие   биты вертикальной  и  горизонтальной  позиции используются для
сравнения  с текущей позицией луча. Позиция и маска проверяются против
текущей  позиции  луча перед тем, как будет проведено любое дальнейшее
действие.  Позиция  луча, заданная в первом слове команды используется
при  сравнении  с  позицией луча только, если включены соответствующие
биты  маски.  Если  биты  маски 0, то сравнение всегда TRUE. Например,
если    вы    хотите   использовать  значения  только  первых  4х  бит
вертикальной позиции установите в слове маски биты 8-11

Не все биты позиции луча могут быть замаскированы. Если вы посмотрите
на  описание  второго слова команд WAIT и SKIP, вы обнаружите, что бит
15  -  это  бит  окончания работы блиттера. Этот бит не входит в маску
сравнения,  он  имеет  свое  собственное  значение  в  команде.  Таким
образом,  вы не можете маскировать старший бит в командах WAIT и SKIP.
В  большинстве  ситуаций  это ограничение не существенно, но следующий
пример показывает как быть, в случае, если это необходимо.

Этот  пример  заставляет  коппер  выдавать  прерывание каждые 16 строк
развертки.  Может показаться, что это можно сделать, задав маску $0F и
сравнивая  результат  с $0F. Это будет выдавать TRUE для $1F,$2F,$3F и
т.д.  Но на самом деле, поскольку старший бит нельзя замаскировать, то
он  будет  появляться  в  сравнении.  Когда коппер будет ожидать $0F в
вертикальной  позиции  после 128 ($80) сравнение будет всегда выдавать
TRUE.  В  этом  случае минимальное значение, которое всегда больше $0F
это  $80  и  прерывания  будут  происходить  каждую строку. Запомните,
коппер сравнивает по принципу больше или равно.

В  следующем  примере  копперлист  организован в цикл. Значения COP1LC
и COP2LC устанавливаются процессором перед запуском копперлиста. Также
необходимо правильно установить обработчик прерываний коппера, которые
будут    генерироваться   каждые   16   линий.   Экран   должен   быть
неинтерлейсный.

КАК ЭТО РАБОТАЕТ
Оба  цикла  одинаковы  по  логике.  В  каждом  коппер  ждет достижения
регистром    вертикальной    позиции   значения   $?F   (?   -   любая
шестнадцатиричная  цифра) и выдает прерывание коппера. Для уверенности
в  том,  что  коппер  не зациклится на одной линии и не будет выдавать
прерывания  на  одной  линии, ожидаем горизонтальной позиции $E2 после
выдачи   каждого   прерывания.   Эта   позиция   - последняя доступная
горизонтальная позиция. Это будет отправлять коппер на следующую линию
перед  следующим  WAIT. Цикл выполняется записью 0 в регистр COPJMP1 и
коппер переходит на адрес, записанный в COP1LC.
Проблема  маски,  описанная  выше, разрушает этот алгоритм после 127-й
строки.  Для исправления этого используется отдельный цикл для позиций
больших  или  равных  127.  Когда  вертикальная  позиция  переходит за
линию  127,  первая  команда  цикла пропускается и коппер переходит во
второй  цикл.  Он  такой-же,  как  и  первый, за исключением того, что
ожидается  линия  $?F со включенным старшим битом (двоичное 1xxx1111).
Это    используется    для   обоих   команд   WAIT   (вертикальной   и
горизонтальной).  Для зацикливания второго цикла используется запись в
регистр COPJMP2. Выход из цикла происходит при достижении вертикальной
позиции  255.  После этого копперлист заканчивается ожиданием $FFFE. В
начале   следующего   обратного   хода   луча   коппер   автоматически
перезапускается с адреса COP1LC.

ПРИМЕЧАНИЕ
Регистр  COP1LC  записывается  обработчиком  графических  прерываний в
цепочке  прерываний  обратного хода луча. Если этот обработчик будет в
сохранности, COP1LC будет правильно запускаться каждый кадр.
;
; Это данные для копперлиста.
;
; Требуется, чтобы адрес COPPERL1 был загружен в COP1LC, а COPPERL2 в
; COP2LC
;
COPPERL1:
     DC.W    $0F01,$8F00     ; Ждем VP=0xxx1111
     DC.W    INTREQ,$8010    ; Включаем прерывание коппера

     DC.W    $00E3,$80FE     ; Ждем $E2 по горизонтали
                             ; Это  дает  завершение строки, чтобы не
                             ; вызвать прерывание  еще  раз

     DC.W    $7F01,$7F01     ; Пропускаем если VP>=127
     DC.W    COPJMP1,$0      ; Первый цикл по COP1LC

COPPERL2:
     DC.W    $8F01,$8F00     ; Ждем Vp=1xxx1111
     DC.W    INTREQ,$8010    ; Включаем прерывание коппера

     DC.W    $80E3,$80FE     ; Ждем $E2 по горизонтали
                             ; Это  дает  завершение строки, чтобы не
                             ; вызвать прерывание  еще  раз

     DC.W    $FF01, $FE01    : Пропускаем если VP>=255
     DC.W    COPJMP2,$0      ; Второй цикл по COP2LC


;  Здесь может быть любой код копперлиста, поскольку в NTSC 262 линии,
; а мы остановились на 255-й, доступно немного лишнего времени

     DC.W    $FFFF,$FFFE     ; Конец копперлиста

ИСПОЛЬЗОВАНИЕ КОППЕРА В РЕЖИМЕ ИНТЕРЛЕЙСА

Битпланы  в  режиме  интерлейса вдвое выше, чем нормальные. Нормальный
экран в NTSC 262 линии, в интерлейсе - 524 линии, в PAL соответственно
312  и  625  линий.  В  режиме интерлейса видео луч дважды проходит по
экрану  от верха до низа, изображая в случае NTSC по 262 линии за раз.
Во время первого прохода изображаются нечетные линии, во время второго
-  четные,  которые  переплетаются с нечетными. Экран интерлейса можно
представить  как два поля, одно из которых содержит четные строки, а
второе  -  нечетные. Рисунок 2-1 показывает как располагается в памяти
интерлейсный экран.

   Нечетное поле           Четное поле
     (время t)            (время t+16.6ms)         Данные в памяти
                                                    _____________
                                                   |             |
                                                   |      1      |
                                                   |_____________|
                                                   |             |
    _____________          _____________           |      2      |
   |             |        |             |          |_____________|
   |      1      |        |      2      |          |             |
   |_____________|        |_____________|          |      3      |
   |             |        |             |          |_____________|
   |      3      |        |      4      |          |             |
   |_____________|        |_____________|          |      4      |
   |             |        |             |          |_____________|
   |      5      |        |      6      |          |             |
   |_____________|        |_____________|          |      5      |
                                                   |_____________|
                                                   |             |
                                                   |      6      |
                                                   |_____________|

                Рис 2-1: Интерлейсный экран в памяти

Система выбирает данные для битпланов используя указатели на начальные
адреса  данных в памяти. Как вы можете видеть, начальный адрес четного
экрана  на  одну  линию больше, чем нечетного. Следовательно указатели
битпланов   должны   содержать   разные   значения  для  разных  полей
интерлейсного экрана
Подобная  организация данных в памяти похожа на организацию экрана (т.
е. четные и нечетные линии переплетаются) Это заставляет создавать два
раздельных копперлиста для управления изображением данных.
Для  выполнения  этого  вы можете установить прерывание, которое будет
изменять  содержимое регистра COP1LC для указания каждый раз на другой
копперлист.
Для подробностей об интерлейсных экранах см. главу 3 'Экраны'

ИСПОЛЬЗОВАНИЕ КОППЕРА С БЛИТТЕРОМ

Если  коппер  используется  для  запуска  последовательности  операций
блиттера,  он  должен ждать прерывания окончания работы блиттера перед
запуском очередной операции. Изменение регистров блиттера во время его
работы   может  привести  к  непредсказуемым  результатам.  Для  этого
существует  специальный  бит  -  бит  окончания  работы блиттера (BFD)
Обычно  этот бит = 1 и в операциях сравнения участвуют только счетчики
позиции луча.
Когда бит BFD = 0 логика работы команды WAIT изменяется. Теперь коппер
будет  ждать  достижения  лучем  заданной  позиции  и окончания работы
блиттера. Блиттер заканчивает, когда бит BFD устанавливается. Этот бит
надо   сбрасывать  осторожно,  чтобы  не  нарушить  никаких  регистров
блиттера.

Для подробностей использования блиттера см. главу 6 'Блиттер'

КОППЕР И 68000

Если  вам  не  достаточно  команд  коппера  вы можете прервать 68000 и
использовать   его   команды.   68000   может  прерываться  различными
устройствами  путем установки флагов прерывания в регистре INTREQ. Для
прерывания  коппера  надо  записать  следующие биты в регистр INTREQ с
помощью команды MOVE:

Табл. 2-1: Прерывание 68000

   Номер бита     Название   Функция

     15           SET/CLR    Определяет, устанавливаются или
                             сбрасываются биты, равные 1

      4           COPEN      Прерывание коппера

См.  главу  7  "Управление  чипсетом" для более подробной информации о
прерываниях


ОБЗОР КОМАНД КОППЕРА

Следующая таблица показывает значения бит для всех команд коппера. См.
приложение A для обзора всех регистров.

       Табл. 2-2: Команды коппера

             Move             Wait             Skip
  бит#    IR1     IR2      IR1     IR2      IR1    IR2

   15      X     RD15      VP7     BFD      VP7    BFD
   14      X     RD14      VP6     VE6      VP6    VE6
   13      X     RD13      VPS     VES      VPS    VES
   12      X     RD12      VP4     VE4      VP4    VE4
   11      X     RD11      VP3     VE3      VP3    VE3
   10      X     RD10      VP2     VE2      VP2    VE2
   09      X     RD09      VP1     VE1      VP1    VE1
   08     DA8    RD08      VP0     VE0      VP0    VE0
   07     DA7    RD07      HP8     HE8      HP8    HE8
   06     DA6    RD06      HP7     HE7      HP7    HE7
   05     DAS    RD05      HP6     HE6      HP6    HE6
   04     DA4    RD04      HPS     HES      HPS    HES
   03     DA3    RD03      HP4     HE4      HP4    HE4
   02     DA2    RD02      HP3     HE3      HP3    HE3
   01     DA1    RD01      HP2     HE2      HP2    HE2
   00      0     RD00       1       0        1      1

X   = не используется, но должен содержать 0 (для совместимости)
IR1 = первое слово команды
IR2 = второе слово команды
DA  = aдрес нaзнaчения
RD  = дaнные для перемещения
VP  = бит вертикaльной позиции лучa
HP  = бит горизонтaльной позиции лучa
VE  = бит мaски вертикaльной позиции луча
HE  = бит мaски горизонтaльной позиции луча
BFD = бит "окончание работы блиттера"

End.

 


НОМЕ