┌──────────────────────────────┐
│ │
│ ЧИТАТЕЛЬ - ЧИТАТЕЛЮ │
│ │
└──────────────────────────────┘
(c) Иван Рощин, г.Москва, 1997.
Драйвер экрана для компьютера
"Пентагон-128".
Предлагаю вашему вниманию
драйвер экрана - небольшую про-
цедуру на ассемблере (211 байт),
вызываемую по прерываниям 2-го
рода. Используя этот драйвер,
очень легко написать программу,
реализующую полноэкранный MULTI-
COLOR - эффект ( каждая строка
вместе с бордюром рисуется своим
цветом). При этом все проблемы,
связанные с различной синхрони-
зацией на разных типах компьюте-
ров, решаются простой заменой
драйвера (предлагаемый вариант
рассчитан на "Пентагон-128").
Вот пример программы, исполь-
зующей драйвер для реализации
простейшего эффекта - по экрану
движутся три цветные полосы. Об-
ратите особое внимание на то,
как программируется этот эффект,
а также на длину программы -
всего 217 байт (без драйвера).
140.
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
;---------------------------------------
2
Несколько замечаний по поводу
программы:
- Вы можете увидеть недокументи-
рованную команду INC XL. Такое
ее обозначение воспринимается
ассемблером ZX ASM 3.0. Но в
других ассемблерах, а также в
отладчике STS она обозначается
как INC LX (код DD 2C).
- строки программы, помеченные
комментарием "WAIT", нужны
только для задержки.
- адрес начала массива DATA обя-
зательно должен быть нечетным.
При работе с драйвером прог-
раммист может считать, что ви-
деопамять - это массив данных,
расположенный по адресу DATA и
занимающий столько байт, сколько
строк MULTICOLOR'а он хочет ви-
деть на экране. Значение каждого
байта этого массива - число от 0
до 7, определяющее цвет соответ-
ствующей строки экрана. Если
массив не изменяется, MULTICO-
LOR-эффект будет неподвижным.
Чтобы он двигался, необходимо
каждые 1/50 секунды (или реже)
изменять данные в массиве.
Вертикальный размер MULTI-
COLOR'а в знакоместах опреде-
ляется значением переменной N.
Это значение может быть не лю-
бым, а лишь в границах 1..7
и 31..37 включительно. Дело в
том, что условие окончания рабо-
ты драйвера проверяется только
тогда, когда текущая строка це-
ликом относится к бордюру (либо
в верхней, либо в нижней части
экрана).
Даже если у Вас "Пентагон-
128", драйвер может работать не
очень хорошо (полосы мигают и т.
п.). Дело в том, что даже у ком-
пьютеров одного типа положение
INT'а относительно кадрового
синхроимпульса может колебаться.
В этом случае можно попробовать
подстроить значение задержки в
драйвере. Для этого найдите ко-
манды, помеченные "WAIT", в са-
мом начале драйвера. Вы увидите
такой фрагмент:
147.
LD D,H ;WAIT
LD E,L ;WAIT
LD BC,171 ;WAIT
LDIR ;WAIT
2
Добиться наилучшего качества
изображения можно, изменяя заг-
ружаемое в 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 (или
вместе с ним) и вызывать в нуж-
ный момент нажатием пары клавиш.
P.S. Предлагаю объявить конкурс
на лучший графический эф-
фект, созданный с помощью
драйвера.
* * *
Поделитесь вашим мнением о статье