|
Этюды - о табличном программировании.
|
ЭТЮДЫ
© А.Астафьев, г.Новосибирск
КОРР: То, что вы назвали "гасилкой экрана", называется FADE-OUT эффектом (это принято во всем мире), а "зажигалка", соответственно, называется FADE-IN эффектом.
Проанализировав предыдущие процедуры, я пришел к выводу, что все забыли об одном замечательном методе программирования - табличном программировании. А зря. Порой, метод табличного программирования дает изящное, простое и, главное, быстродействующее решение. Ниже, как иллюстрацию данного метода, я привожу FADE-OUT, гасящую экран "как в TERMINATORS".
|
ORG |
#8000 |
PREPARE |
LD |
HL,DAL_TBL |
PREP_T |
LD |
A, L |
|
AND |
7 |
|
JR |
z, $+3 |
|
DEC |
A |
|
LD |
E,A |
|
LD |
A, L |
|
AND |
#38 |
|
JR |
Z, $ + 4 |
|
SUB |
8 |
|
OR |
E |
|
LD |
(HL),A |
|
INC |
L |
|
JR |
NZ,PREP_T |
FADEOUT |
LD |
D,DAL_TBL/256 |
|
LD |
B, 7 |
W_RAY |
HALT |
|
|
LD |
HL,#5800 |
ATR_DEC |
LD |
E,(HL) |
|
LD |
A,(DE) |
|
LD |
(HL),A |
|
INC |
HL |
|
LD |
A, H |
|
CP |
#5B |
|
JR |
C,ATR_DEC |
|
DJNZ |
W_RAY |
|
RET |
|
|
ORG |
$FF00+256 |
DAL_TBL |
DEFS |
256 |
в D - старший байт адреса таблицы
ровно 7 переходов
ждем сканирования экрана
это адрес атрибутов
берем код атрибута
и заменяем его значением из таблицы повторяем 7 68 раз до конца области атрибутов
адрес таблицы на 256 байт
выравниваем резервируем
Пару слов по данной процедуре. Написана она в TASM128, который легко дает возможность определить адреса таблиц, кодов и т.п. более простыми методами, чем ZEUS. Сама же процедура создает для своей работы таблицу из 256 байт. Таблица располагается по адресу, выровненному на 256 - с такими таблицами процессору проще работать, так как от элемента к элементу в таблице можно переходить командами INC L или DEC L (предполагаем, что адрес таблицы находится в HL), а от таблицы к таблице переходить командами INC H / DEC H. Аналогичным образом, элементарно находятся и элементы в таких таблицах. Порой, достаточно загрузить номером элемента младшую часть адресного регистра. Вдобавок ко всему, подобные таблицы (если, конечно, занимаются все 256 байт таблицы) обладают способностью "заворота". Вот простой пример:
повторяем 7 раз на случай белого цвета
HL,#BE00 A,STEP A, L L,A
(POINTER+1) A, (HL)
Здесь каким бы ни было значение STEP - мы можем "летать" по таблице, перескакивая хоть по 50 элементов, но никогда не вырвемся за ее пределы!
Если требовался бы двухбайтный результат - легко продолжить:
INC H
LD H, (HL)
LD L,A
Но вернемся-таки к нашей процедуре FADE-OUT. Если не быть буквоедом, пожертвовать памятью, то можно написать процедуру - рекордсмен по длине. Пусть дополнительно использованы 2048 байтов, пусть предварительно нужно прогнать процедуру, которая выстраивает эту таблицу, но зато какой результат! И все как в TERMINATORS!
|
ORG |
#8000 |
PAL_TBL |
EQU |
0-256*8 |
FADEOUT |
LD |
D,PAL_TBL/256 |
W_RAY |
HALT |
|
|
LD |
H, #5A |
ATR_DEC |
LD |
E,(HL) |
|
LD |
A,(DE) |
|
LD |
(HL),A |
|
DEC |
HL |
|
BIT |
3,H |
|
JR |
NZ,ATR_DEC |
|
INC |
D |
|
JR |
NZ,W_RAY |
|
RET |
|
PREPARE |
LD |
HL,PAL_TBL |
|
LD |
BC,#0800 |
FILL_T |
LD |
A, L |
|
AND |
7 |
|
JR |
z, $+3 |
|
DEC |
A |
|
LD |
E,A |
|
LD |
A, L |
|
AND |
#38 |
|
JR |
Z, $ + 4 |
|
SUB |
8 |
|
OR |
E |
|
LD |
(HL),A |
|
CP I |
|
|
JP |
PE, FILL_T |
|
RET |
|
LITRLE TRICK
Сама процедура FADE-OUT занимает 17 байт. Для приготовления таблицы можно использовать несколько модифицированную PREPARE. И под конец, для затравки умов читателей, приведу пример процедуры установки точки на экран, которая, во-первых, сама по себе работает очень быстро, и, во-вторых, также является иллюстрацией табличных методов программирования. Из особенностей этой процедуры приведу следующую - не требуется никаких дополнительных вычислений, чтобы ограничить размер экрана по Y-координате. Вследствие того, что для точек с координатами больше 191, таблица просто заполнена нулями - точка просто не ставится на экран, процедура посылает данные в адрес 0...31, где находится ПЗУ. Таблица занимает 1K памяти и, конечно же, выровнена на адрес, кратный 256. Я называю такие адреса -"адресами начала параграфа", где параграф - блок 256 байтов с адреса, кратного 256. Вообще, во всех 8-битных процессорах такие блоки называют страницами (64K=256 страниц по 256 байт), но я, чтобы избежать путаницы со страницами 128-ого Спектрума, называю их параграфами. PSET
SET TBL
LD |
H,SCR_TBL/256 |
H - начало таблицы |
|
|
LD |
L, E |
в L загружаем X-координату |
|
LD |
C, (HL) |
берем байт с необходимым битом |
|
INC |
H |
шагаем к следующему |
параграфу |
|
LD |
A, (HL) |
берем значение X/8 - |
это номер |
столбца |
INC |
H |
|
|
|
LD |
L, D |
теперь нужна Y-координата |
|
OR |
(HL) |
HL указывает сейчас |
на младшую |
часть адреса |
INC |
H |
|
|
|
LD |
H, (HL) |
берем старшую часть |
адреса |
|
LD |
L,A ; |
в HL - адрес точки, |
в C - нужный бит |
LD |
A, (HL) |
ставим точку по OR |
|
|
OR |
C |
|
|
|
LD |
(HL),A |
|
|
|
RET |
|
|
|
|
LD |
HL,SCR_TBL |
в HL - адрес таблицы |
|
SET DOT
SET_DIV
SET_ADR
LD |
B, L |
; |
в B=00, так как таблица выровнена |
LD |
A, #80 |
; |
начинаем от старшего бита |
LD |
(HL),A |
; |
и заносим его в список |
RRCA |
|
; |
переходим к следующему биту |
INC |
HL |
|
|
DJNZ |
SET_DOT |
; |
и так 256 раз |
LD |
A, L |
|
|
RRCA |
|
; |
три вращения для деления на 8 |
RRCA |
|
|
|
RRCA |
|
|
|
AND |
31 |
; |
а можно бы было дать три раза SRL A |
LD |
(HL),A |
; |
так мы заносим в (HL) значение L деленное |
INC |
HL |
|
|
DJNZ |
SET_DIV |
; |
и так 256 раз |
LD |
B, #C0 |
; |
требуется 192 экранных адреса |
LD |
DE,#4000 |
; |
адрес левого столбца - самая верхушка |
LD |
(HL),E |
|
|
INC |
H |
|
|
LD |
(HL),D |
; |
грузим DE в два параграфа. E в первый; D |
на 8
H
L
D_STEP SET_ADR
второй
D_STEP
D
A, D
7
NZ A, E A,32 E,A
C
A, D
8
D,A
DEC
INC
CALL
DJNZ
RET
INC
LD
AND
RET
LD
ADD
LD
RET
LD
SUB
LD
RET
ORG
DEFS
смещаем на байт (точку) ниже повторим 192 раза
смещаемся на 256 в экране - байт вниз проверка - это следующее знакоместо?
если нет - вернемся обратно сместимся на знакоместо вниз (+32)
должны перейти в следующую треть - возвращаемся иначе компенсируем результат восьми INC D возвращаем адрес в текущую треть экрана (треть, кстати, равна 256*8=2048 (256=INC D))
$FF00+256 256*4
резервируем 1K нулей средствами TASM12 8
SCR_TBL
Здесь процедура SET_TBL подготавливает эту таблицу. Сама таблица выглядит следующим обра-
зом:
#8100 256 байт - байты с установленным битом в соответствии с X. #8200 256 байт - значение в таблице = ее индекс/b (b - номер столбца (X)). #8300 192 байта в начале - младший байт адреса левого столбца экрана. #8400 первые 192 байта - аналогично, старшие байты.
Вот такие вот "пироги". Думаю, недолго домыслить, что с начала параграфа удобно хранить не только таблицы. Там можно размещать спрайты, фонт (что те же самые спрайты и есть), многобайтные переменные (для этого группируйте их), и т.д. и т.п. Кстати, не забывайте, что родной фонт размещается с адреса #3D00 - суть начала параграфа. Аналогично, и экран Спектрума тоже.
СОДЕРЖАНИЕ:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Форум-Игры - рассмотрены следующие игры: Venturama, The sceptre, Carrier command, Elite, Sim city, Robin of the wood, Think, Hacker 2, Rampage, Звёздное наследие, "A.T.F.", Colony.
-
Перекресток - рассмотрены следующие адвентюры: He-man, Hampstead, Звёздное наследие, Rebel planet, The famous five, Terrormolinos, Sam spoon, Spiderman, Kentilla, Heavy on the magic, Magnetic moon.
-
-
-
-
-
-
-
-
-
-
-
-
-
|
|