Страница Ивана Рощина > Статьи >

© Иван Рощин, Москва

ZXNet: 500:95/462.53
E-mail: bestview@mtu-net.ru
WWW: http://www.ivr.da.ru

Драйвер экрана для компьютера «Пентагон-128»

(«ZX-Ревю» 3—4/1997)
(Дата последнего редактирования: 23.10.2002)

    Предлагаю вашему вниманию драйвер экрана — небольшую процедуру на ассемблере (211 байтов), вызываемую по прерываниям 2-го рода. Используя этот драйвер, очень легко написать программу, реализующую полноэкранный multicolor-эффект (каждая строка вместе с бордюром рисуется своим цветом). При этом все проблемы, связанные с различной синхронизацией на разных типах компьютеров, решаются простой заменой драйвера (предлагаемый вариант рассчитан на «Пентагон-128»).

    Вот пример программы, использующей драйвер для реализации простейшего эффекта: по экрану движутся три цветные полосы. Обратите особое внимание на то, как программируется этот эффект, а также на длину программы — всего 217 байтов (без драйвера).

        ORG     #6000

;Основная программа:

N       EQU     37  ;Размер по вертикали в знакоместах.

        LD      HL,#5800 ;Установка
        LD      DE,#5801 ;атрибутов
        LD      BC,#2FF  ;(не обязательно).
        LD      (HL),L
        LDIR

;Рисуем сетку (необходимо для multicolor'а):

        LD      HL,#4000
LP1     XOR     A
        BIT     0,H
        JR      NZ,NE_FF
        CPL
NE_FF   LD      (HL),A
        INC     HL
        LD      A,H
        CP      #58
        JR      NZ,LP1

;Инициализация эффекта:

        CALL    E_INIT

;Чтобы вызывать драйвер по прерываниям,
;формируем таблицу, например, с адреса
;#FEFE:

        LD      HL,#FE00
        LD      B,0
LOOPT   LD      (HL),#62
        INC     HL
        DJNZ    LOOPT
        LD      (HL),#62
        LD      A,#FE
        LD      I,A
        IM      2

LOOP_M  HALT
        CALL    EFFECT
        IN      A,(254)  ;что-то нажато?
        CPL
        AND     %00011111
        JR      Z,LOOP_M ;если нет
        IM      1
        RET              ;выход из программы

;---------------------------------------
;Реализация эффекта "цветные полосы":

;Точка входа для инициализации:

E_INIT  LD      HL,DATA+40
        LD      DE,DATA+41
        LD      BC,300
        LD      (HL),0
        LDIR
        LD      HL,DATA
        LD      DE,DATA+1
        LD      BC,39
        LD      (HL),7
        LDIR
        RET

;Точка входа для вызова раз в прерывание:

EFFECT  LD      HL,(A_BEG)
        LD      B,1
        LD      A,(A_WAY)
        CALL    MOVE
        LD      (A_WAY),A
        LD      (A_BEG),HL

        LD      HL,(B_BEG)
        LD      B,2
        LD      A,(B_WAY)
        CALL    MOVE
        CALL    MOVE
        LD      (B_WAY),A
        LD      (B_BEG),HL

        LD      HL,(C_BEG)
        LD      B,4
        LD      A,(C_WAY)
        CALL    MOVE
        CALL    MOVE
        CALL    MOVE
        LD      (C_WAY),A
        LD      (C_BEG),HL

        RET

;Процедура MOVE сдвигает полосу:

MOVE    AND     A
        JR      NZ,MOVE_D

;Сдвиг вверх:

        LD      A,H
        OR      L
        JR      Z,MOVE_D
MOVE_UP DEC     HL
        PUSH    HL
        LD      DE,DATA
        ADD     HL,DE
        LD      A,(HL)
        OR      B
        LD      (HL),A
        LD      DE,40
        ADD     HL,DE
        LD      A,(HL)
        XOR     B
        LD      (HL),A
        POP     HL
        XOR     A
        RET

;Сдвиг вниз:

MOVE_D  LD      DE,297-40
        AND     A
        SBC     HL,DE
        PUSH    AF
        ADD     HL,DE
        POP     AF
        JR      Z,MOVE_UP
        PUSH    HL
        LD      DE,DATA
        ADD     HL,DE
        LD      A,(HL)
        XOR     B
        LD      (HL),A
        LD      DE,40
        ADD     HL,DE
        LD      A,(HL)
        OR      B
        LD      (HL),A
        POP     HL
        INC     HL
        LD      A,1
        RET

A_BEG   DW      0  ;координаты
B_BEG   DW      0  ;полос
C_BEG   DW      0

A_WAY   DB      0  ;направление
B_WAY   DB      0  ;движения
C_WAY   DB      0

;---------------------------------------

        ORG     #6262

;=======================================
;Драйвер экрана:

        DI
        PUSH    AF  ;Сохраняем значения
        PUSH    BC  ;используемых
        PUSH    DE  ;регистров.
        PUSH    HL
        PUSH    IX
        PUSH    IY
        LD      (M122+1),SP

;Задержка, пока луч не дойдет до верхней строки:

        LD      D,H    ;WAIT
        LD      E,L    ;WAIT
        LD      BC,171 ;WAIT
        LDIR           ;WAIT

        LD      IX,DATA+1 ;адрес таблицы
        LD      HL,#5720  ;текущий адрес атрибутов
        LD      BC,3      ;B - всегда 0, C - счетчик.
        LD      A,(DATA)  ;цвет первой строки
        LD      YL,A      ;запомнили цвет
        LD      DE,#20

;Луч в начале очередной строки:

M3      LD      SP,HL
        SBC     HL,DE

        LD      A,YL
        OUT     (254),A

        LD      A,(IX+1)
        LD      YL,A
        AND     A
        RLCA
        RLCA
        RLCA
        OR      (IX)
        LD      D,A

        LD      A,H
        CP      #58
        JR      C,NO_ATR
        CP      #5B
        JR      NC,NO_ATR2

;Половина строки уже прорисована,
;и атрибуты можно сменить.

        LD      E,D
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE

;16 байтов заполнены, луч в начале
;следующей строки:

        LD      A,D
        AND     7
        OUT     (254),A
        LD      A,C

;Меняем оставшиеся атрибуты:

        LD      C,#20  ;BC=#20
        ADD     HL,BC
        LD      SP,HL
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        PUSH    DE
        LD      C,A
        INC     XL
        LD      A,0    ;WAIT

NEXT_L  LD      DE,#10
        INC     IX
        DEC     C
        JR      NZ,M10

        LD      C,4
        ADD     HL,DE
        JR      M3

M10     SBC     HL,DE
        JP      M3

;Сюда попадаем, если текущая строка
;целиком относится к бордюру:

NO_ATR  LD      A,0 ;WAIT
        LD      A,0 ;WAIT

;Проверка по значению HL: не пора ли
;выйти из прерывания?

NO_ATR2 LD      DE,#5720+((N-1)*#20)
        AND     A
        SBC     HL,DE
        JR      NC,M122
        ADD     HL,DE

        LD      DE,(0)  ;WAIT
        LD      DE,(0)  ;WAIT
        NOP             ;WAIT

        LD      A,(IX)
        OUT     (254),A

        LD      A,(IX)  ;WAIT
        LD      A,(IX)  ;WAIT
        LD      A,(IX)  ;WAIT
        LD      A,(IX)  ;WAIT
        INC     DE      ;WAIT

        LD      DE,#20
        ADD     HL,DE
        INC     XL
        JR      NEXT_L

;Выход из прерывания:

M122    LD      SP,0
        POP     IY    ;восстанавливаем
        POP     IX    ;значения регистров
        POP     HL
        POP     DE
        POP     BC
        XOR     A
        OUT     (254),A
        POP     AF
        EI
        RET

;=======================================

        ORG     #7001

;---------------------------------------
;Массив данных для multicolor'а:

DATA    DS      320

    Несколько замечаний по поводу программы:

    При работе драйвера программист может считать, что видеопамять — это массив данных, расположенный по адресу DATA и занимающий столько байтов, сколько строк multicolor'а он хочет видеть на экране. Значение каждого байта этого массива — число от 0 до 7, определяющее цвет соответствующей строки экрана. Если массив не изменяется, multicolor-эффект будет неподвижным. Чтобы он двигался, необходимо каждые 1/50 секунды (или реже) изменять данные в массиве.

    Вертикальный размер multicolor'а в знакоместах определяется значением переменной N. Это значение может быть не любым, а лишь в границах 1-7 (рис. 1) и 31-37 (рис. 2) включительно. Дело в том, что условие окончания работы драйвера проверяется только тогда, когда текущая строка целиком относится к бордюру (либо в верхней, либо в нижней части экрана).

Рис. 1

Рис. 2

    Чтобы подстроить значение задержки в драйвере, найдите команды, помеченные «WAIT», в самом начале драйвера. Вы увидите такой фрагмент:

        LD      D,H    ;WAIT
        LD      E,L    ;WAIT
        LD      BC,171 ;WAIT
        LDIR           ;WAIT

    Добиться наилучшего качества изображения можно, изменяя загружаемое в BC число или добавляя NOP'ы (или и то, и другое). Следить за результатом внесённых изменений удобно, если при каждом запуске программы на экране появляется неподвижная картинка с разноцветными линиями. Для этого нужно убрать строки CALL E_INIT и CALL EFFECT, а вместо строки DATA DS 320 поместить такие строки:

  DATA    DB      7,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,0
          DB      4,0,4,0,4,0,4,7
          DB      0,1,2,3,4,5,6,7
          DB      4,0,4,0,4,0,4,0
          .......................

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

    Если вы всё же решили программировать multicolor-эффекты, не используя драйвер, вам придётся тщательно подсчитывать, за сколько тактов выполняется тот или иной участок программы. Так как постоянно искать в справочнике сведения о длительности выполнения то одной, то другой команды может быть неудобно, рекомендую использовать для этой цели программу «HELP_Z80» — электронный справочник по командам микропроцессора Z80, который можно загрузить в любой ассемблер вместо отладчика STS (или вместе с ним) и вызывать в нужный момент нажатием пары клавиш.

    Дополнение: графические эффекты, получаемые с помощью описанного в статье драйвера, вы можете увидеть в моём demo «Ray».

Другие мои статьи о программировании графических эффектов:

1. 

«Два графических эффекта». «ZX-Ревю» 3—4/1997.

2. 

«Графический эффект „цветные полосы“». «ZX-Ревю» 7—10/1997.

3. 

«Несколько графических эффектов». «ZX-Ревю» 11—12/1997.

4. 

«Графический эффект „iris“». ZX Format #8, Adventurer #8.

5. 

«Улучшенный эффект из demo „Art Vision“». Adventurer #8.

6. 

«Оптимизация на примере intro „Start“». «Радиомир. Ваш компьютер» 7—10/2001.

Страница Ивана Рощина > Статьи >