ZX Review
#3-4
22 июля 1997 |
|
Читатель-читателю - И.Рощин. Драйвер экрана для компьютера "Пентагон-128".
┌──────────────────────────────┐ │ │ │ ЧИТАТЕЛЬ - ЧИТАТЕЛЮ │ │ │ └──────────────────────────────┘ (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. Предлагаю объявить конкурс на лучший графический эф- фект, созданный с помощью драйвера. * * *
Другие статьи номера:
Похожие статьи:
В этот день... 21 ноября