ZX Guide
#01
27 ноября 1998 |
|
Ликбез - горе от ума: о выводе экрана за прерывание
К вопросу о выводе экрана за прерывание Alone Coder В первом номере компьютерного журнала ZX-Power была опубикована статья,автор ко- торой,призвав в помощь математику,убедите- льно опроверг программистскую легенду, о том,что кто-то якобы бросил экран (без ат- рибутов, т.е.6144 байт) за одно прерывание Пентагона (71680 тактов процессора). Автор был прав и не прав одновременно. Прав он был в том,что в 1996 году никто из программистов не писал вышеуказанного эф- фекта.Не прав же он был в том,что по своей предубежденности о невозможности реализа- ции вышеупомянутого эффекта он пропустил 1 (один) способ вывода экрана,а именно метод LD-PUSH. Метод POP-PUSH нуждается в частой модификации указателя стека SP и потому не обеспечивает нужной скорости; метод же LD- PUSH модифицирует стек вдвое реже. Вот о чем я говорю: LD SP,... LD DE,xx PUSH DE LD DE,yy PUSH DE ... Можно указать мне на то,что в указанной статье шла речь о перемещении экрана,а мой метод выводит лишь те данные, которые ука- заны непосредственно в программе вывода. Это неверно: LD тоже считывает данные, но лежащие лишь в определенной области памя- ти. Этот недостаток искупают три преимуще- ства: освобождение регистров позволяет мо- дифицировать SP вычислениями;последнее да- ет возможность перемещать приемник данных, что не позволяет метод POP-PUSH; однотип- ность операций в программе упрощает реали- зацию. Покажу,как использовать метод,в частно- сти,для плавного скроллинга вверх. PROG ;начало программы вывода DOWN SP ┐ ┐ │ LD DE,nn├16 раз├192 раза PUSH DE │ │ ┘ ┘ JP PROG Под DOWN SP подразумевается процедурка, которая рассчитывает адрес строки, лежащей на одну ниже указанной в HL,и помещает его в SP.Простейший пример такой процедурки: SET 7,H LD E,(HL) INC L LD D,(HL) EX DE,HL LD SP,HL Она использует таблицу, лежащую в адре- сах #C000Ў#D800 и занимает 35 тактов. Вна- чале я ее и использовал,но из-за ее медли- тельности мне пришлось пожертвовать двумя крайними столбцами экрана,то есть програм- ма уже не удовлетворяла заданному условию. Если изменить ее по такому образцу,то ско- рость будет вполне соответствовать требуе- мой: SET 7,H LD SP,HL POP HL LD SP,HL Этот вариант использует аналогичную та- блицу,но ест уже 30 тактов.Финальный штрих в процедуру: INC H RRCA ┌─JR NC,$+6 │ SET 7,H │ LD SP,HL │ POP HL ╘LD SP,HL Теперь используется только 28+3/8 такта (в регистре A установлен один бит, поэтому центральная часть вызывается 1 раз из 8). Если заменить JR на JP,то всего 28 тактов. Программа замкнута на себя. Как же ее вызывать? Заводим в основной программе (диспетче- ре) счетчик,который указывает на некоторую строку из 192, которые выводит программа. Записываем туда breakpoint, т.е. JP USE, и прыгаем в программу в обход процедуры мо- дификации SP (о которой я только что гово- рил). Выглядит это примерно так: BEGIN LD (HL),195 INC HL LD DE,USE LD (HL),E INC HL LD (HL),D PUSH HL LD DE,6 ADD HL,DE LD (USE+1),SP PUSH HL LD HL,#4020;конец 1-й строки экрана LD A,128 RET USE LD SP,0 POP HL LD (HL),код jr nc DEC HL LD (HL),код rrca DEC HL LD (HL),код inc h LD DE,4*16+9 ADD HL,DE BIT 7,(HL) JR Z,$+5 LD HL,PROG;если дошли до конца JR BEGIN Чтобы вставить HALT, нужно завести еще один счетчик (например,HL'),который указы- вал бы на 96 строчек ниже первого,а вместо breakpoint'а ставить JP (IX),где IX=IMER IMER LD SP,0 EXX HALT LD (HL),код rrca DEC L LD (HL),код inc h PUSH HL EXX RET Как выводить буквы? По одной строчке: в ту строчку, которая освободилась после из- менения счетчика N 1, в параметры LD надо записать соответствующие линии букв.Не мне вам об этом писать: вы и сами знаете, как это делается, а коли не знаете,так еще ин- тереснее будет открыть это для себя. Программа, которая изображает эффект сдвига вверх с аршинными буквами, есть в Приложении. Она называется PUSHROLL.H. P.S.: одна из демонстраций с FUNTOP '98выводит экран в прерывание,но это, по-видимому, какой-то другой эффект, поскольку в ее же эпилоге сдвиг происходит как всегда,классический,- за два.
Другие статьи номера:
Похожие статьи:
В этот день... 2 декабря